<?php
    
    class UserHandler{
    	
		private $m_DBConnection = NULL;
		private $m_usersTableName = "users";
		private $m_passwordhashColumnName = "PasswordHash";
		private $m_temppasswordColumnName = "Temppassword";
		private $m_saltColumnName = "Salt";
		
		
		 /* CREATE TABLE  `testlogin`.`Users` (
			`Username` VARCHAR( 32 ) NOT NULL ,
			 `PasswordHash` VARCHAR( 32 ) NOT NULL ,
			 `Salt` VARCHAR( 10 ) NOT NULL ,
		     `Temppassword` VARCHAR( 32 ) NOT NULL ,
			PRIMARY KEY (  `Username` )
			) ENGINE = INNODB DEFAULT CHARSET = utf8;
		 */
		
		public function __construct(DBConnection $aDBConnection){
			$this->m_DBConnection = $aDBConnection;
		}
		
		//Function to Add a new User to the Database
		//Returns true if successful
		public function AddUser($username,$password)
		{
			if($this->CheckIfUserExists($username) == true){
				return false;
			}
			
			if(Validate::ValidatePassword($password) == false){
				return false;
			}
			
			if ($username != Validate::StripAll($username)){
				return false;
			}
			
			if(strlen($username) == 0){
				return false;
			}
			
			$salt = $this->GenerateRandomSalt();
			$password = $this->HashPassword($password, $salt);
			
			$sql = "INSERT INTO $this->m_usersTableName VALUES(?, '$password', '$salt', '')";
	                
	        $aStatement = $this->m_DBConnection->Prepare($sql);
			
	      	$aStatement->bind_param("s", $username);
				
			$aStatement->execute();
			
			$tempPassword = $this->GenerateTempPassword($username);
			$this->SaveTempPassword($username, $tempPassword);
			
			return true;
		}
		
		//Function to remove a user from the Databas
		//Returns true if successful
		public function RemoveUser($username){
			
			if($this->CheckIfUserExists($username) == false){
				return false;
			}
			$sql = "DELETE FROM $this->m_usersTableName WHERE Username = ?";
	                
	        $aStatement = $this->m_DBConnection->Prepare($sql);
			
	      	$aStatement->bind_param("s", $username);
				
			$aStatement->execute();
			
			return true;
		}
		
		function CheckIfUserExists($username){
			$sql = "SELECT * FROM $this->m_usersTableName WHERE Username = ?";
                
            $aStatement = $this->m_DBConnection->Prepare($sql);
                
            $aStatement->bind_param("s", $username);
			
			$aStatement->execute();
			$result = $aStatement->get_result();
			
			if($result->num_rows == 1){
				return true;
			}
			return false;
		}
		
		//Check the username and password against the database. Returns true if it is possible to login with the current info.
		function CheckLogin($username,$password){
			
			$sql = "SELECT * FROM $this->m_usersTableName WHERE Username = ?";
                
            $aStatement = $this->m_DBConnection->Prepare($sql);
                
            $aStatement->bind_param("s", $username);
			
			$UserArray = $this->m_DBConnection->GetSingleLineAsAssociativeArray($aStatement);
			
			//Returns false if the username doesn't exist in the database
			if($UserArray == NULL)
			{
				return false;
			}
			// compare the password to a temporary passwordhash
			if($UserArray[$this->m_temppasswordColumnName] === $password)
			{			
				return true;
			}
			
			// Hash the password and compare it to the passwordhash
			if($this->HashPassword($password, $UserArray[$this->m_saltColumnName]) == $UserArray[$this->m_passwordhashColumnName]){
				return true;
			}
			return false;
		}
		
		// Function to generate a temporary password for a specific user
		// Returns the generated password
		function GenerateTempPassword() {
	
			$chars = "abcdefghijklmnopqrstuvwxyz0123456789"; 
		    $i = 0; 
		    $pass = '' ; 
		
		    while ($i <= 7) { 
		        $num = rand() % 35; 
		        $tmp = substr($chars, $num, 1); 
		        $pass = $pass . $tmp; 
				$i++;
		    } 
			$salt = $this->GenerateRandomSalt();
			
			$pass= $this->Hashpassword($pass,$salt);
			
    		return $pass; 	
		}
		
		// Saves a temporary password in the database for a specific user
		function SaveTempPassword($username, $tempPassword)
		{
			$sql = "UPDATE $this->m_usersTableName SET $this->m_temppasswordColumnName = '$tempPassword' WHERE Username = ?";

			$aStatement = $this->m_DBConnection->Prepare($sql);

            $aStatement->bind_param("s", $username);
			
			$aStatement->execute();
		}
		
		function GenerateRandomSalt(){
			$chars = "abcdefghijklmnopqrstuvwxyz0123456789";
			$i = 0;  
			$salt = '' ;
		
		    while ($i <= 9) { 
				$num = rand() % 35;
				$tmp = substr($chars, $num, 1); 
				$salt = $salt . $tmp;
		        $i++; 
		    } 
			return $salt;
		}
		
		function HashPassword($password, $salt){
			if (strlen($password) == 32){
				return $password;
			}
			
			return md5($password . $salt);
		}
		
		public function Test(){
			$this->RemoveUser("testUser42");
			$this->RemoveUser("AGoodUsername");
			$this->RemoveUser("");
			
			$this->AddUser("testUser42","testPassword42");
			if($this->CheckIfUserExists("testUser42") == false){
				Log::LogMessage("AddUser is not working as intended");
				return false;
			}
			if($this->AddUser("","testPassword42") == true){
				Log::LogMessage("AddUser is not working as intended");
				return false;
			}
			if($this->AddUser("AGoodUsername","short") == true){
				Log::LogMessage("AddUser is not working as intended");
				return false;
			}
			if($this->AddUser("<a href='Something'>blabla</a>","short") == true){
				Log::LogMessage("AddUser is not working as intended");
				return false;
			}
			$this->RemoveUser("testUser42");
			if($this->CheckIfUserExists("testUser42") == true){
				Log::LogMessage("RemoveUser is not working as intended");
				return false;
			}
			return true;
			
		}
    }
